package com.iaiai.imail.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 有关日期的操作用此类完成
 * 
 * @author 水季
 * @version 1.0, 2005/4/24
 */
public class DateUtil {

	public static void main(String[] args) throws ParseException {
		Calendar cal = Calendar.getInstance();
		// // cal.set(Calendar.DATE, 1);
		// System.out.println(cal.get(Calendar.MONTH));
		// cal.add(Calendar.DAY_OF_WEEK, -6);
		// cal.add(Calendar.DAY_OF_MONTH, -11);
		// System.out.println(DateUtil.formatDate(cal.getTime(), "yyyy-MM-dd"));
		// System.out.println(getWeekDate(formatDate("2011-11-11"),1));
		System.out.println(DateUtil.getWeekOfYear(formatDate("2011-1-1")));
		System.out.println(DateUtil.getFirstDayOfWeek(formatDate("2011-1-1")));
		System.out.println(DateUtil.getYearWeekEndDay(2010, 52));
		System.out.println(getWeek());
		// System.out.println(cal.MONDAY);
		// System.out.println(getBetweenDays("2012-1-2", "2009-1-1"));
	}

	/**
	 * 返回当前时间
	 * 
	 * @return
	 */
	public static String getDate() {
		return formatDate(new Date());
	}

	/**
	 * 返回当前时间
	 * 
	 * @return
	 */
	public static String getDateTime() {
		return formatDateYMDHMS(new Date());
	}

	/**
	 * 获得当前年
	 * 
	 * @return
	 */
	public static int getYear() {
		return getYear(Calendar.getInstance().getTime());
	}

	/**
	 * 获得当前年
	 * 
	 * @param date
	 *            时间
	 * @return
	 */
	public static int getYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR);
	}

	/**
	 * 获得当前月，从0开始计算
	 * 
	 * @return
	 */
	public static int getMonth() {
		return getMonth(Calendar.getInstance().getTime());
	}

	/**
	 * 获得当前月，从0开始计算
	 * 
	 * @param date
	 *            当前时间
	 * @return
	 */
	public static int getMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH);
	}

	/**
	 * 获得当前日期
	 * 
	 * @return
	 */
	public static int getDay() {
		return getDay(Calendar.getInstance().getTime());
	}

	/**
	 * 获得当前日期
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static int getDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DATE);
	}

	/**
	 * 得到当前小时
	 * 
	 * @return
	 */
	public static int getHour() {
		return getHour(Calendar.getInstance().getTime());
	}

	/**
	 * 得到当前小时
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static int getHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.HOUR_OF_DAY); // //得到24小时机制的
		// return Calendar.getInstance().get(Calendar.HOUR); ////得到12小时机制的
	}

	/**
	 * 得到分钟
	 * 
	 * @return
	 */
	public static int getMinute() {
		return getMinute(Calendar.getInstance().getTime());
	}

	/**
	 * 得到分钟
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static int getMinute(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MINUTE);
	}

	/**
	 * 得到秒
	 * 
	 * @return
	 */
	public static int getSecond() {
		return getSecond(Calendar.getInstance().getTime());
	}

	/**
	 * 得到秒
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static int getSecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.SECOND);
	}

	/**
	 * 获得毫秒
	 * 
	 * @return
	 */
	public static int getMillisecond() {
		return getMillisecond(Calendar.getInstance().getTime());
	}

	/**
	 * 获得毫秒
	 * 
	 * @param date
	 * @return
	 */
	public static int getMillisecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MILLISECOND);
	}

	public static int getWeek() {
		return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 获取一年的第几周
	 * 
	 * @return
	 */
	public static int getWeekByYear() {
		return getWeekByYear(Calendar.getInstance().getTime());
	}

	/**
	 * 获取一年的第几周，这个方法获得的时候有一个bug，建议用getWeekOfYear
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	@Deprecated
	public static int getWeekByYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 获取一年的第几周，修改bug，测试第2011-1-1应该属于2010年的第52周,2011-1-2应该属于2011年的第1周
	 * 
	 * @param date
	 * @return 返回格式为"yyyy-xx"，xx为周
	 */
	public static String getWeekOfYear(Date date) {
		int year = getYear(date);
		int month = getMonth(date) + 1;
		int day = getDay(date);
		String end = "";

		Calendar c = new GregorianCalendar(year, month - 1, day);
		c.setFirstDayOfWeek(Calendar.SUNDAY); // 设置每周的第一天为星期日
		c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);// 每周从周日开始
		c.setMinimalDaysInFirstWeek(7);
		String firstWeekDay = getYearWeekFirstDay(year, 1);

		int weeks = 1;
		weeks = c.get(Calendar.WEEK_OF_YEAR);

		int ds = date.compareTo(java.sql.Date.valueOf(firstWeekDay));
		end = c.get(Calendar.YEAR) + "-" + weeks;

		if (ds < 0 && month == 1) {
			end = year - 1 + "-" + weeks;
		}
		if (weeks < 10) {
			end = c.get(Calendar.YEAR) + "-0" + weeks;
		}
		return end;
	}

	/**
	 * 获得月的第几周
	 * 
	 * @return
	 */
	public static int getWeekByMonth() {
		return getWeekByMonth(Calendar.getInstance().getTime());
	}

	/**
	 * 获得月的第几周
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static int getWeekByMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_MONTH);
	}

	/**
	 * 格式化日期，默认格式化格式为"yyyy-MM-dd"
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static String formatDate(Date date) {
		return (new SimpleDateFormat("yyyy-MM-dd")).format(date);
	}

	/**
	 * 格式化日期，默认格式化格式为"yyyy-MM-dd HH:mm:ss"
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static String formatDateYMDHMS(Date date) {
		return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date);
	}

	/**
	 * 格式化日期
	 * 
	 * @param date
	 *            日期
	 * @param format
	 *            格式化格式
	 * @return
	 */
	public static String formatDate(Date date, String format) {
		return (new SimpleDateFormat(format)).format(date);
	}

	/**
	 * 字符串转日期，默认格式为"yyyy-MM-dd"
	 * 
	 * @param date
	 *            日期
	 * @return
	 * @throws ParseException
	 */
	public static Date formatDate(String date) throws ParseException {
		return (new SimpleDateFormat("yyyy-MM-dd")).parse(date);
	}

	/**
	 * 字符串转日期，默认格式为"yyyy-MM-dd HH:mm:ss"
	 * 
	 * @param date
	 *            日期
	 * @return
	 * @throws ParseException
	 */
	public static Date formatDateYMDHMS(String date) throws ParseException {
		return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(date);
	}

	/**
	 * 字符串转日期
	 * 
	 * @param date
	 *            日期
	 * @param format
	 *            格式化的格式
	 * @return
	 * @throws ParseException
	 */
	public static Date formatDate(String date, String format)
			throws ParseException {
		return (new SimpleDateFormat(format)).parse(date);
	}

	/**
	 * 获得日期
	 * 
	 * @param time
	 * @return
	 */
	public static Date getDate(long time) {
		return new Date(time);
	}

	/**
	 * 已知年月，计算这月的天数
	 * 
	 * @param year
	 *            年
	 * @param month
	 *            月
	 * @return
	 */
	public static int getDaysByMonth(int year, int month) {
		int days = 0;
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month - 1);
		days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		return days;
	}

	/**
	 * 获取下个季度的日期段(起始日期) type: 1 月 2 季 3 旬
	 * 
	 * @param date
	 *            = "2005-01-01", type = 1 //获取下个月的开始日期
	 * @param date
	 *            = "2005-01-01", type = 2 //获取下个季的开始日期
	 * @param date
	 *            = "2005-01-01", type = 3 //旬没有做
	 * 
	 * @return
	 * @throws ParseException
	 */
	public static String getDate(String date, int type) throws ParseException {
		String[] str = new String[2];
		Date d = formatDate(date);
		int year = getYear(d);
		int month = getMonth(d) + 1;
		int day = getDay(d);

		switch (type) {
		case 1:
			str[0] = String.valueOf(year) + "-" + String.valueOf(month) + "-01";
			if (month == 12) {
				str[1] = String.valueOf(year + 1) + "-01-01";
			} else {
				str[1] = String.valueOf(year) + "-" + String.valueOf(month + 1)
						+ "-01";
			}
			break;
		case 2:
			if (month == 1 || month == 2 || month == 3) {
				str[0] = String.valueOf(year) + "-01-01";
				str[1] = String.valueOf(year) + "-04-01";
			} else if (month == 4 || month == 5 || month == 6) {
				str[0] = String.valueOf(year) + "-04-01";
				str[1] = String.valueOf(year) + "-07-01";
			} else if (month == 7 || month == 8 || month == 9) {
				str[0] = String.valueOf(year) + "-07-01";
				str[1] = String.valueOf(year) + "-10-01";
			} else if (month == 10 || month == 11 || month == 12) {
				str[0] = String.valueOf(year) + "-10-01";
				str[1] = String.valueOf(year + 1) + "-01-01";
			}
			break;
		case 3:
			break;
		}

		return str[1];
	}

	/**
	 * 计算某年某周的开始日期，每周从周日开始
	 * 
	 * 
	 * @param year
	 *            格式 yyyy ，必须大于1900年度 小于9999年
	 * 
	 * @param week
	 *            1到52或者53
	 * @return 日期，格式为yyyy-MM-dd
	 */
	public static String getYearWeekFirstDay(int year, int week) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.SUNDAY); // 设置每周的第一天为星期日
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);// 每周从周日开始

		// 上面两句代码配合，才能实现，每年度的第一个周，是包含第一个星期日的那个周。

		cal.setMinimalDaysInFirstWeek(7); // 设置每周最少为7天

		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, week);

		// 分别取得当前日期的年、月、日
		return formatDate(cal.getTime());
	}

	/**
	 * 计算某年某周的结束日期
	 * 
	 * @param yearNum
	 *            格式 yyyy ，必须大于1900年度 小于9999年
	 * @param weekNum
	 *            1到52或者53
	 * @return 日期，格式为yyyy-MM-dd
	 */
	public static String getYearWeekEndDay(int yearNum, int weekNum) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.SUNDAY); // 设置每周的第一天为星期日
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);// 每周从周日开始，最后一天是周六
		cal.setMinimalDaysInFirstWeek(7); // 设置每周最少为7天
		cal.set(Calendar.YEAR, yearNum);
		cal.set(Calendar.WEEK_OF_YEAR, weekNum);

		return formatDate(cal.getTime());
	}

	/**
	 * 计算指定年度共有多少个周。
	 * 
	 * @param year
	 *            格式 yyyy ，必须大于1900年度 小于9999年
	 * @return
	 */
	public static int getWeekNumByYear(int year) {
		if (year < 1900 || year > 9999) {
			throw new NullPointerException("年度必须大于等于1900年小于等于9999年");
		}
		int result = 52;// 每年至少有52个周 ，最多有53个周。
		String date = getYearWeekFirstDay(year, 53);

		if (date.substring(0, 4).equals(year + "")) { // 判断年度是否相符，如果相符说明有53个周。
			result = 53;
		}
		return result;
	}

	/**
	 * 计算两个日期差
	 * 
	 * @param startDate
	 *            开始日期
	 * @param endDate
	 *            结束日期
	 * @return
	 */
	public static int getBetweenDays(String startDate, String endDate) {
		int intDays = 0;
		try {
			startDate = startDate.replaceAll("-", "/");
			endDate = endDate.replaceAll("-", "/");
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
			Date dt1 = formatter.parse(startDate);
			Date dt2 = formatter.parse(endDate);

			long l = dt1.getTime() - dt2.getTime();
			intDays = (int) (l / (24 * 3600 * 1000));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return intDays;
	}

	/**
	 * 间隔时间的计算
	 * 
	 * @param date
	 *            日期
	 * @param type
	 *            为1时，返回当前日期加val的日期<br>
	 *            为2时，返回当前周加val的周的星期一<br>
	 *            为3时，返回当前月加val的月的日期<br>
	 *            为4时，返回当前年加val的年的日期<br>
	 * @param val
	 *            间隔数
	 * 
	 * @return
	 */
	public static String getSpaceDate(String date, int type, int val) {
		String str = "";
		try {
			Calendar cal = Calendar.getInstance();
			cal.setTime(formatDate(date));

			switch (type) {
			case 1: // 日
				cal.add(cal.DATE, val);
				break;
			case 2: // 周
				cal.add(cal.DATE, 7 * val);
				break;
			case 3: // 月
				cal.add(cal.MONDAY, val);
				break;
			case 4: // 年
				cal.add(cal.YEAR, val);
				break;
			}

			str = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return str;
	}

	/**
	 * 获得第几周
	 * 
	 * @param year
	 *            年
	 * @param week
	 *            第几周
	 * @return
	 */
	public static Date getFirstDayOfWeek(int year, int week) {
		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, 1);

		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, week * 7);
		return getFirstDayOfWeek(cal.getTime());
	}

	/**
	 * 获得周一日期，星期一为星期第一天
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static Date getFirstDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
		return c.getTime();
	}

	/**
	 * 根据天数推算日期
	 * 
	 * @param date
	 *            日期
	 * @param day
	 *            往前往后的天数
	 * @return
	 */
	public static Date getDateByDay(Date date, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, day);
		return calendar.getTime();
	}

	/**
	 * 处理POI控制EXCEL乱码问题
	 * 
	 * @param src
	 *            String
	 * @return String
	 */
	public String getXlsString(String src) {
		String rightStr = "";
		try {
			rightStr = new String(src.getBytes("UTF-16BE"));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return rightStr;
	}

	/*
	 * 计算生肖
	 */
	public static String getShengxiao(int year) {
		String sxiao = "";
		int start = 1901;
		int x = (start - year) % 12;
		if (x == 1 || x == -11) {
			sxiao = "鼠";
		}
		if (x == 0) {
			sxiao = "牛";
		}
		if (x == 11 || x == -1) {
			sxiao = "虎";
		}
		if (x == 10 || x == -2) {
			sxiao = "兔";
		}
		if (x == 9 || x == -3) {
			sxiao = "龙";
		}
		if (x == 8 || x == -4) {
			sxiao = "蛇";
		}
		if (x == 7 || x == -5) {
			sxiao = "马";
		}
		if (x == 6 || x == -6) {
			sxiao = "羊";
		}
		if (x == 5 || x == -7) {
			sxiao = "猴";
		}
		if (x == 4 || x == -8) {
			sxiao = "鸡";
		}
		if (x == 3 || x == -9) {
			sxiao = "狗";
		}
		if (x == 2 || x == -10) {
			sxiao = "猪";
		}
		return sxiao;
	}

	/**
	 * 计算星座
	 * 
	 * @return
	 */
	public static String getConstellation(int month, int day) {
		if (month == 1 && day >= 20 || month == 2 && day <= 18) {
			return "水瓶座";
		}

		if (month == 2 && day >= 19 || month == 3 && day <= 20) {
			return "双鱼座";
		}

		if (month == 3 && day >= 21 || month == 4 && day <= 19) {
			return "白羊座";
		}

		if (month == 4 && day >= 20 || month == 5 && day <= 20) {
			return "金牛座";
		}

		if (month == 5 && day >= 21 || month == 6 && day <= 21) {
			return "双子座";
		}

		if (month == 6 && day >= 22 || month == 7 && day <= 22) {
			return "巨蟹座";
		}

		if (month == 7 && day >= 23 || month == 8 && day <= 22) {
			return "狮子座";
		}

		if (month == 8 && day >= 23 || month == 9 && day <= 22) {
			return "处女座";
		}

		if (month == 9 && day >= 23 || month == 10 && day <= 22) {
			return "天秤座";
		}

		if (month == 10 && day >= 23 || month == 11 && day <= 21) {
			return "天蝎座";
		}

		if (month == 11 && day >= 22 || month == 12 && day <= 21) {
			return "射手座";
		}

		if (month == 12 && day >= 22 || month == 1 && day <= 19) {
			return "摩羯座";
		}
		return null;
	}

	/**
	 * 计算星座
	 * 
	 * @param month
	 * @param day
	 * @return
	 */
	public static String getConstellation(Date date) {
		return getConstellation(date.getMonth() + 1, date.getDate());
	}

}